home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / µSim 1.0.5 / FabLibsƒ / MovableModal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-30  |  15.1 KB  |  570 lines  |  [TEXT/CWIE]

  1. #include    "UtilsSys7.h"
  2. #include    "CursorBalloon.h"
  3. #include    "FabWList.h"
  4. #include    "Independents.h"
  5. #include    "MovableModal.h"
  6.  
  7. static void RecalcTextItems(DialogRef d, RgnBalloonCursPtr theObj);
  8. static void DoMovableModalUpdate(DialogRef dPtr);
  9. static void DimOrBlackenItems(EventRecord *e, DialogRef w, Boolean active);
  10. static void DoMovableModalMenuEdit(short theItem);
  11. static void DoMovableModalDrag(WindowRef w, Point p);
  12. static void getDragRectMovMod(WindowRef w, RectPtr r);
  13. static TEHandle GetTEIfVisible(DialogRef dPtr, short editTextExists);
  14.  
  15. static Handle    sControlItemList = nil;
  16. static short    sDefaultItem = 0, sCancelItem = 0;
  17.  
  18. #define    FabSetDialogDefaultItem(d, i)    sDefaultItem = i
  19. #define    FabSetDialogCancelItem(d, i)    sCancelItem = i
  20.  
  21. short HandleMovableModalDialog(/*ModalFilterProcPtr filterProc,*/
  22.                     dialogItemsPtr things,
  23.                     PointPtr    dialogTopLeft,
  24.                     Boolean (*canAcceptDrag)(const HFSFlavor *),
  25.                     OSErr (*dialogDragReaction)(WindowRef, const HFSFlavor *),
  26.                     void (*initProc)(DialogPtr),
  27.                     void (*cleanupProc)(DialogPtr),
  28.                     void (*userProc)(DialogPtr, Handle, short),
  29.                     void (*AdjustMenus)(TEHandle),
  30.                     void (*Handle_My_Menu)(long),
  31.                     void (*DomyKeyEvent)(EventRecord *),
  32.                     Boolean (*PreProcessKeyDown)(EventRecord *, DialogPtr),
  33.                     void (*PostProcessKeyDown)(EventRecord *, DialogPtr),
  34.                     void (*DoUpdate)(EventRecord *),
  35.                     void (*DoActivate)(EventRecord *),
  36.                     void (*DoHiLevEvent)(EventRecord *),
  37.                     void (*DoOSEvent)(EventRecord *),
  38.                     void (*DoIdle)(void),
  39.                     unsigned long minimumSleep,
  40.                     short resId)
  41. {
  42. EventRecord    lMyEvent;
  43. Rect    box;
  44. Handle    item;
  45. GrafPtr    port;
  46. long    myRefCon;
  47. DialogRef    dPtr;
  48. DialogRef    dSelPtr;
  49. WindowRef    w;
  50. FabWindowPtr    thefabw;
  51. unsigned long    movablemodalSleep;
  52. dialogItemsPtr    spanPtr;
  53. dialogItemsPtr    itemToBeActivated;
  54. RgnHandle    theRgn;
  55. long    menuSelected;
  56. short    wMenu;
  57. short    code, type, theItemHit = memFullErr;
  58. short    theGroup, theFakeItem, lastItemClosingDialog = cancel;
  59. short    theType, iNum;
  60. short    editTextExists = 0;
  61. unsigned char    keypressed;
  62. Boolean    dialoging;
  63.  
  64. InitCursor();
  65.  
  66. dPtr = GetNewDialog(resId, nil, (WindowRef)-1L);
  67. if (dPtr) {
  68.     GetPort(&port);
  69.     SetGrafPortOfDialog(dPtr);
  70.  
  71.     thefabw = AddWindowToList(dPtr);
  72.     SetUpdate(thefabw, DoMovableModalUpdate);
  73.     SetActivate(thefabw, DimOrBlackenItems);
  74.     SetGetDragRect(thefabw, getDragRectMovMod);
  75.     SetCanIAcceptDrag(thefabw, canAcceptDrag);
  76.     SetDragReaction(thefabw, dialogDragReaction);
  77.     
  78.     if (dialogTopLeft) {
  79.         if (IsOnScreenWeak(*dialogTopLeft))
  80.             MoveWindow(GetDialogWindow(dPtr), dialogTopLeft->h, dialogTopLeft->v, false);
  81.         }
  82.  
  83.     sDefaultItem = 0;
  84.     sCancelItem = 0;
  85.     
  86.     spanPtr = things;
  87.     sControlItemList = NewHandle(0);
  88.     if (sControlItemList) {
  89.         while (iNum = spanPtr->itemNumber) {
  90.             myRefCon = spanPtr->refCon;
  91.             GetDialogItem(dPtr, iNum, &type, &item, &box);
  92.             theType = type & itemDisable ? type - itemDisable : type;
  93.             switch(theType) {
  94.                 case ctrlItem+btnCtrl:
  95.                         {
  96.                         if (myRefCon == 1L)
  97.                             FabSetDialogDefaultItem(dPtr, iNum)
  98.                             ;
  99.                         else if (myRefCon == 2L)
  100.                             lastItemClosingDialog = iNum;
  101.                         if (iNum == cancel)
  102.                             FabSetDialogCancelItem(dPtr, iNum)
  103.                             ;
  104.                         }
  105.                     SetControlReference((ControlHandle)item, (*(ControlHandle)item)->contrlHilite);
  106.                     PtrAndHand(&item, sControlItemList, sizeof item);
  107.                     break;
  108.                 case ctrlItem+chkCtrl:
  109.                 case ctrlItem+radCtrl:
  110.                     if (myRefCon > 0) {
  111.                         SetControlValue((ControlHandle)item, 1);
  112.                         if (userProc)
  113.                             userProc(dPtr, item, iNum);
  114.                         }
  115.     /*                else if (myRefCon == 0) {
  116.                         if (userProc)
  117.                             userProc(dPtr, item, iNum);
  118.                         }*/
  119.                     else if (myRefCon < 0)
  120.                         HiliteControl((ControlHandle)item, 255);
  121.                     SetControlReference((ControlHandle)item, (*(ControlHandle)item)->contrlHilite);
  122.                     PtrAndHand(&item, sControlItemList, sizeof item);
  123.                     break;
  124.                 case ctrlItem+resCtrl:
  125.                     if (myRefCon)
  126.                         SetControlValue((ControlHandle)item, myRefCon);
  127.                     SetControlReference((ControlHandle)item, (*(ControlHandle)item)->contrlHilite);
  128.                     PtrAndHand(&item, sControlItemList, sizeof item);
  129.                     break;
  130.                 case statText:
  131.                     if (myRefCon)
  132.                         SetDialogItemText(item, (StringPtr)myRefCon);
  133.                     break;
  134.                 case editText:
  135.                     SetDialogItemText(item, (StringPtr)myRefCon);
  136.                     if(editTextExists == 0) {
  137.                         editTextExists = iNum;
  138.                         }
  139.                     if (theRgn = NewRgn()) {
  140.                         RectRgn(theRgn, &box);
  141.                         InstallRgnHandler(thefabw, theRgn, RecalcTextItems, GetCursor(iBeamCursor),
  142.                                 0, 0, iNum);
  143.                         }
  144.                     break;
  145.         //        case iconItem:
  146.         //            break;
  147.         //        case picItem:
  148.         //            break;
  149.                 case userItem:
  150.                     SetDialogItem(dPtr, iNum, type, (Handle)myRefCon, &box);
  151.                     break;
  152.                 }
  153.             spanPtr++;
  154.             }
  155.         item = nil;
  156.         PtrAndHand(&item, sControlItemList, sizeof item);
  157.         if (editTextExists) {
  158.             ResizeObjects(dPtr);
  159.             RecalcGlobalCoords(thefabw);
  160.             (void) EventAvail(0, &lMyEvent);
  161.             RecalcMouseRegion(dPtr, lMyEvent.where);
  162.             movablemodalSleep = GetCaretTime();
  163.             }
  164.         else
  165.             movablemodalSleep = -1L;
  166.         if (initProc)
  167.             initProc(dPtr);
  168. //            (void)TEFeatureFlag(teFOutlineHilite, TEBitSet, ((DialogPeek)dPtr)->textH);
  169.         SelectDialogItemText(dPtr, editTextExists, 0, SHRT_MAX);
  170.         ShowWindow(GetDialogWindow(dPtr));
  171.     
  172.         dialoging = true;
  173.         HiliteMenu(0);
  174.         AdjustMenus(GetTEIfVisible(dPtr, editTextExists));
  175.         DrawMenuBar();
  176.  
  177.         movablemodalSleep = MIN(minimumSleep, movablemodalSleep);
  178.         do {
  179.             if (WaitNextEvent(everyEvent - diskMask, &lMyEvent, movablemodalSleep, mouseRgn)) {
  180.                 if (IsDialogEvent(&lMyEvent)) {
  181.                     theFakeItem = 0;
  182.                     switch (lMyEvent.what) {
  183.                         //case mouseDown :
  184.                         //    DebugStr("\pMouse Down!");
  185.                         //    break;
  186.                         case keyDown:
  187.                         case autoKey:
  188.                             keypressed = CHARFROMMESSAGE(lMyEvent.message);
  189.                             if (PreProcessKeyDown ? PreProcessKeyDown(&lMyEvent, dPtr) : true) {
  190.                                 if (keypressed == 3) {
  191.                                     theFakeItem = sDefaultItem;
  192.                                     if (theFakeItem == 0)
  193.                                         theFakeItem = ok;
  194.                                     }
  195.                                 else if (keypressed == 13 && sDefaultItem) {
  196.                                     theFakeItem = sDefaultItem;
  197.                                     }
  198.                                 else if (CmdPeriodOrEsc(&lMyEvent)) {
  199.                                     theFakeItem = sCancelItem;
  200.                                     }
  201.                                 else if (keypressed == 27) { // clear key
  202.                                     //SelIText(dPtr, ((DialogPeek)dPtr)->editField + 1, 0, SHRT_MAX);
  203.                                     DialogDelete(dPtr);
  204.                                     }
  205.                                 else if ((unsigned short)lMyEvent.message == kHelpKey) {
  206.                                     (void)HMSetBalloons(1 - HMGetBalloons());
  207.                                     //RecalcMouseRegion(dPtr, lMyEvent.where);
  208.                                     }
  209.                                 else if (lMyEvent.modifiers & cmdKey) {
  210.                                     AdjustMenus(GetTEIfVisible(dPtr, editTextExists));
  211.                                     menuSelected = MenuKey(keypressed);
  212.                                     if ((wMenu = HiWord(menuSelected)) && wMenu == kRes_Menu_Edit) {
  213.                                         DoMovableModalMenuEdit(LoWord(menuSelected));
  214.                                         HiliteMenu(0);
  215.                                         }
  216.                                     else
  217.                                         Handle_My_Menu(menuSelected);
  218.                                     }
  219.                                 else
  220.                                     (void) DialogSelect(&lMyEvent, &dSelPtr, &theItemHit);
  221.                                 if (theFakeItem)
  222.                                     FlashButton(dPtr, theFakeItem);
  223.                                 if (PostProcessKeyDown)
  224.                                     PostProcessKeyDown(&lMyEvent, dPtr);
  225.                                 }
  226.                             break;
  227.                         case updateEvt:
  228.                             if ((DialogPtr)lMyEvent.message == dPtr) {
  229.                                 BeginUpdate(GetDialogWindow(dPtr));
  230.                                 DoMovableModalUpdate(dPtr);
  231.                                 EndUpdate(GetDialogWindow(dPtr));
  232.                                 }
  233.                             else
  234.                                 DoUpdate(&lMyEvent);
  235.                             break;
  236.                         case activateEvt :
  237.                             DoActivate(&lMyEvent);
  238.                             break;
  239.                         case kHighLevelEvent:
  240.                             DoHiLevEvent(&lMyEvent);
  241.                             break;
  242.                         case osEvt :
  243.                             DoOSEvent(&lMyEvent);
  244.                             break;
  245.                         default:
  246.                             if (DialogSelect(&lMyEvent, &dSelPtr, &theItemHit)) {
  247.                                 if (dSelPtr == dPtr && theItemHit) {
  248.                                     theFakeItem = theItemHit;
  249.                                     }
  250.                                 }
  251.                         }
  252.                     if (theFakeItem) {
  253.                         GetDialogItem(dPtr, theFakeItem, &type, &item, &box);
  254.                         switch (type) {
  255.                             case ctrlItem+btnCtrl:
  256.                                 if ((theFakeItem >= ok) && (theFakeItem <= lastItemClosingDialog))
  257.                                     dialoging = false;
  258.                                 else if (userProc)
  259.                                     userProc(dPtr, item, theFakeItem);
  260.                                 break;
  261.                             case ctrlItem+chkCtrl:
  262.                                 SetControlValue((ControlHandle)item, 1 - GetControlValue((ControlHandle)item));
  263.                                 if (userProc)
  264.                                     userProc(dPtr, item, theFakeItem);
  265.                                 break;
  266.                             case ctrlItem+radCtrl:
  267.                                 if (GetControlValue((ControlHandle)item) == 0) {
  268.                                     SetControlValue((ControlHandle)item, 1);
  269.                                     for (spanPtr = things; (++spanPtr)->itemNumber != theFakeItem; )
  270.                                         ;
  271.                                     itemToBeActivated = spanPtr;
  272.                                     for (theGroup = spanPtr->group; (--spanPtr)->group == theGroup; )
  273.                                         ;
  274.                                     while ((++spanPtr)->refCon <= 0L)
  275.                                         ;
  276.                                     GetDialogItem(dPtr, spanPtr->itemNumber, &type, &item, &box);
  277.                                     SetControlValue((ControlHandle)item, 0);
  278.                                     spanPtr->refCon = 0L;
  279.                                     itemToBeActivated->refCon = 1L;
  280.                                     if (userProc)
  281.                                         userProc(dPtr, item, theFakeItem);
  282.                                     }
  283.                                 break;
  284.                             case ctrlItem+resCtrl:
  285.                             case editText:
  286.                             case userItem:
  287.                                 if (userProc)
  288.                                     userProc(dPtr, item, theFakeItem);
  289.                                 break;
  290.                             }
  291.                         }
  292.                     }
  293.                 else switch (lMyEvent.what) {
  294.                     case mouseDown :
  295.                         code = FindWindow(lMyEvent.where, &w);
  296.                         switch (code) {
  297.                             case inMenuBar :
  298.                                 AdjustMenus(GetTEIfVisible(dPtr, editTextExists));
  299.                                 menuSelected = MenuSelect(lMyEvent.where);
  300.                                 if ((wMenu = HiWord(menuSelected)) && wMenu == kRes_Menu_Edit) {
  301.                                     DoMovableModalMenuEdit(LoWord(menuSelected));
  302.                                     HiliteMenu(0);
  303.                                     }
  304.                                 else
  305.                                     Handle_My_Menu(menuSelected);
  306.                                 break;
  307.                             case inSysWindow :
  308.                                 SystemClick(&lMyEvent, w);
  309.                                 AdjustMenus(nil);
  310.                                 break;
  311.                             case inContent :
  312.                                 SysBeep(30);
  313.                                 break;
  314.                             case inDrag :
  315.                                 DoMovableModalDrag(w, lMyEvent.where);
  316.                                 break;
  317.                             case inGoAway :
  318.                                 if (TrackGoAway(w, lMyEvent.where)) {
  319.         
  320.                                     }
  321.                                 break;
  322.     /*                        case inZoomIn :
  323.                             case inZoomOut :
  324.                                 break;
  325.     */                        }
  326.                         break;
  327.                     case keyDown:
  328.                     case autoKey:
  329.                         DomyKeyEvent(&lMyEvent);
  330.                         break;
  331.                     case updateEvt :
  332.                         DoUpdate(&lMyEvent);
  333.                         break;
  334.                     case activateEvt :
  335.                         DoActivate(&lMyEvent);
  336.                         break;
  337.                     case kHighLevelEvent:
  338.                         DoHiLevEvent(&lMyEvent);
  339.                         break;
  340.                     case osEvt :
  341.                         DoOSEvent(&lMyEvent);
  342.                         break;
  343.                     }
  344.                 }
  345.             else {
  346.                 if (IsDialogEvent(&lMyEvent))
  347.                     (void) DialogSelect(&lMyEvent, &dSelPtr, &theItemHit);
  348.                 DoIdle();
  349.                 }
  350.             }
  351.         while (dialoging);
  352.     
  353.         if (theFakeItem == ok) {
  354.             spanPtr = things;
  355.             while (iNum = spanPtr->itemNumber) {
  356.                 GetDialogItem(dPtr, iNum, &type, &item, &box);
  357.                 theType = type & itemDisable ? type - itemDisable : type;
  358.                 switch(theType) {
  359.                     case ctrlItem+chkCtrl:
  360.                     case ctrlItem+resCtrl:
  361.                         spanPtr->refCon = GetControlValue((ControlHandle)item);
  362.                         break;
  363.                     case editText:
  364.                         GetDialogItemText(item, (StringPtr)spanPtr->refCon);
  365.                         break;
  366.             //        case iconItem:
  367.             //            break;
  368.             //        case picItem:
  369.             //            break;
  370.             //        case userItem:
  371.             //            break;
  372.                     }
  373.                 spanPtr++;
  374.                 }
  375.             }
  376.         DisposeHandle(sControlItemList);
  377.         sControlItemList = nil;
  378.         if (cleanupProc)
  379.             cleanupProc(dPtr);
  380.         }
  381.     if (dialogTopLeft) {
  382.         *dialogTopLeft = topLeft(GetWindowPort(GetDialogWindow(dPtr))->portRect);
  383.         LocalToGlobal(dialogTopLeft);
  384.         }
  385.     RemoveWindowFromList(dPtr);
  386.     DisposeDialog(dPtr);
  387.     SetPort(port);
  388.     AdjustMenus(nil);
  389.     DrawMenuBar();
  390.     }
  391. else
  392.     SysBeep(30);
  393. InitCursor();
  394. return theFakeItem;
  395. }
  396.  
  397. void RecalcTextItems(DialogRef d, RgnBalloonCursPtr theObj)
  398. {
  399. Rect    tempRect;
  400. Handle    item;
  401. short    type;
  402.  
  403. GetDialogItem(d, theObj->itemID, &type, &item, &tempRect);
  404. RectRgn(theObj->zoneLocal, &tempRect);
  405. }
  406.  
  407. void DoMovableModalUpdate(DialogRef dPtr)
  408. {
  409. UpdateDialog(dPtr, dPtr->visRgn);
  410. if (sDefaultItem)
  411.     OutlineButton(dPtr, sDefaultItem);
  412. }
  413.  
  414. void DimOrBlackenItems(EventRecord *passEvt, DialogRef w, Boolean active)
  415. {
  416. ControlHandle    itemHandle;
  417. ControlHandle    *scanPtr;
  418. DialogPtr    theDialog;
  419. short    theItemHit;
  420. unsigned char    hiliting;
  421.  
  422. if (sControlItemList) {
  423.     HLockHi(sControlItemList);
  424.     scanPtr = (ControlHandle *)*sControlItemList;
  425.     while (itemHandle = *scanPtr++) {
  426.         if (active)
  427.             hiliting = GetControlReference(itemHandle);
  428.         else {
  429.             SetControlReference(itemHandle, (*itemHandle)->contrlHilite);
  430.             hiliting = 255;
  431.             }
  432.         if (hiliting != (*itemHandle)->contrlHilite) {
  433.             HiliteControl(itemHandle, hiliting);
  434.             ValidRect(&(*itemHandle)->contrlRect);
  435.             }
  436.         }
  437.     HUnlock(sControlItemList);
  438.     }
  439. if (sDefaultItem)
  440.     OutlineButton(w, sDefaultItem);
  441. (void) DialogSelect(passEvt, &theDialog, &theItemHit);
  442. }
  443.  
  444. void DoMovableModalMenuEdit(short theItem)
  445. {
  446. DialogRef    dd;
  447.  
  448. if (SystemEdit(theItem - 1) == false) {
  449.     dd = FrontWindow();
  450.     if (dd && isMovableModal(dd))
  451.         switch (theItem) {
  452. //        case kMItem_Undo:
  453. //            break;
  454.             case kMItem_Cut:
  455.                 DialogCut(dd);
  456.                 ZeroScrap();
  457.                 (void) TEToScrap();
  458. //                PostEvent(keyDown, kCutKey);
  459.                 break;
  460.             case kMItem_Copy:
  461.                 DialogCopy(dd);
  462.                 ZeroScrap();
  463.                 (void) TEToScrap();
  464. //                PostEvent(keyDown, kCopyKey);
  465.                 break;
  466.             case kMItem_Paste:
  467.                 (void) TEFromScrap();
  468.                 DialogPaste(dd);
  469. //                PostEvent(keyDown, kPasteKey);
  470.                 break;
  471.             case kMItem_Clear:
  472.                 DialogDelete(dd);
  473.                 break;
  474.             case kMItem_Select_All:
  475.                 SelectDialogItemText(dd, ((DialogPeek)dd)->editField + 1, 0, SHRT_MAX);
  476.                 break;
  477.             }
  478.     }
  479. }
  480.  
  481. void DoMovableModalDrag(WindowRef w, Point p)
  482. {
  483. EventRecord    tempEvt;
  484. GrafPtr        savePort;
  485. WindowRef    f;
  486. FabWindowPtr    thefabw;
  487. register void (*theProc)(WindowRef);
  488. //register RectPtr    wStateP;
  489.  
  490. f = FrontWindow();
  491. if (w != f && isMovableModal(f))
  492.     SysBeep(30);
  493. else {
  494.     DragWindow(w, p, &qd.screenBits.bounds);
  495.     GetPort(&savePort);
  496.     SetPortWindowPort(w);
  497.     if (thefabw = GetFabWindowPtr(w)) {
  498.         theProc = thefabw->dragProc;
  499.         if (theProc)
  500.             theProc(w);
  501.         RecalcGlobalCoords(thefabw);
  502.         }
  503.     (void) EventAvail(0, &tempEvt);
  504.     RecalcMouseRegion(w, tempEvt.where);
  505.     SetPort(savePort);
  506.     }
  507. }
  508.  
  509. void getDragRectMovMod(WindowRef w, RectPtr r)
  510. {
  511. *r = GetWindowPort(w)->portRect;
  512. }
  513.  
  514. void FabHiliteControl(ControlRef theControl, short hiliteState)
  515. {
  516. HiliteControl(theControl, hiliteState);
  517. SetControlReference(theControl, (*theControl)->contrlHilite);
  518. }
  519.  
  520. TEHandle GetTEIfVisible(DialogPtr dPtr, short editTextExists)
  521. {
  522. Rect    tempRect, resultR;
  523. Handle    item;
  524. short    type;
  525. TEHandle    retTE = nil;
  526.  
  527. if (editTextExists && GetDialogKeyboardFocusItem(dPtr) > 0) {
  528.     GetDialogItem(dPtr, GetDialogKeyboardFocusItem(dPtr), &type, &item, &tempRect);
  529.     if (SectRect(&tempRect, &GetWindowPort(GetDialogWindow(dPtr))->portRect, &resultR))
  530.         retTE = ((DialogPeek)dPtr)->textH;
  531.     }
  532. return retTE;
  533. }
  534.  
  535. void EnableCutCopyPaste(MenuRef editMenu, TEHandle activeTE)
  536. {
  537. long    offset;
  538.  
  539. if (activeTE) {
  540.     EnableItem(editMenu, kMItem_Select_All);
  541.     if ( (*activeTE)->selStart < (*activeTE)->selEnd ) {
  542.         EnableItem(editMenu, kMItem_Cut);
  543.         EnableItem(editMenu, kMItem_Copy);
  544.         EnableItem(editMenu, kMItem_Clear);
  545.         }
  546.     else {
  547.         DisableItem(editMenu, kMItem_Cut);
  548.         DisableItem(editMenu, kMItem_Copy);
  549.         DisableItem(editMenu, kMItem_Clear);
  550.         }
  551.     if (GetScrap(nil, 'TEXT', &offset)  > 0)
  552.         EnableItem(editMenu, kMItem_Paste);
  553.     else
  554.         DisableItem(editMenu, kMItem_Paste);
  555.     }
  556. else {
  557.     DisableCutCopyPaste(editMenu);
  558.     }
  559. }
  560.  
  561. void DisableCutCopyPaste(MenuRef editMenu)
  562. {
  563. short    i;
  564.  
  565. DisableItem(editMenu, kMItem_Undo);
  566. for (i = kMItem_Cut; i <= kMItem_Select_All; i++)
  567.     DisableItem(editMenu, i);
  568. }
  569.  
  570.